<script setup lang="tsx">
import type { IDomEditor, IEditorConfig } from '@wangeditor/editor'
import type { PropType } from 'vue'
import { i18nChangeLanguage } from '@wangeditor/editor'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { ElMessage } from 'element-plus'
import { IsUtils } from 'fetm-utils'
import {
  computed,
  nextTick,
  onBeforeUnmount,
  ref,
  shallowRef,
  unref,
  watch,
} from 'vue'
import { propTypes } from '../../../helpers/propTypes'
import '@wangeditor/editor/dist/css/style.css'

defineOptions({
  name: 'Editor',
})

const props = defineProps({
  editorId: propTypes.string.def('wangeEditor-1'),
  height: propTypes.oneOfType([Number, String]).def('50vh'),
  editorConfig: {
    type: Object as PropType<Partial<IEditorConfig>>,
    default: () => undefined,
  },
  modelValue: propTypes.string.def(''),
  mode: {
    type: String as PropType<'edit' | 'preview'>,
    default: () => 'edit',
  },
})
const emit = defineEmits(['change', 'update:modelValue'])
i18nChangeLanguage('zh-CN')
// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef<IDomEditor>()
const valueHtml = ref('')
watch(
  () => props.modelValue,
  (val: string) => {
    if (val === unref(valueHtml))
      return
    valueHtml.value = val
  },
  {
    immediate: true,
  },
)
// 监听
watch(
  () => valueHtml.value,
  (val: string) => {
    emit('update:modelValue', val)
  },
)
function handleCreated(editor: IDomEditor) {
  editorRef.value = editor
}
// 编辑器配置
const editorConfig = computed((): IEditorConfig => {
  return Object.assign(
    {
      readOnly: false,
      customAlert: (s: string, t: string) => {
        switch (t) {
          case 'success':
            ElMessage.success(s)
            break
          case 'info':
            ElMessage.info(s)
            break
          case 'warning':
            ElMessage.warning(s)
            break
          case 'error':
            ElMessage.error(s)
            break
          default:
            ElMessage.info(s)
            break
        }
      },
      autoFocus: false,
      scroll: true,
      uploadImgShowBase64: true,
    },
    props.editorConfig || {},
  )
})
const editorStyle = computed(() => {
  return {
    height: IsUtils.isNumber(props.height) ? `${props.height}px` : props.height,
  }
})
// 回调函数
function handleChange(editor: IDomEditor) {
  emit('change', editor)
}
// 组件销毁时，及时销毁编辑器
onBeforeUnmount(() => {
  const editor = unref(editorRef.value)
  if (editor === null)
    return
  // 销毁，并移除 editor
  editor?.destroy()
})
async function getEditorRef(): Promise<IDomEditor> {
  await nextTick()
  return unref(editorRef.value) as IDomEditor
}
defineExpose({
  getEditorRef,
})
</script>

<template>
  <div class="border-1-solid">
    <!-- 工具栏 -->
    <Toolbar
      v-show="props.mode == 'edit'"
      :editor="editorRef"
      :editor-id="editorId"
      class="border-bottom-1-solid"
    />
    <!-- 编辑器 -->
    <Editor
      v-model="valueHtml"
      :editor-id="editorId"
      :default-config="editorConfig"
      :style="editorStyle"
      @on-change="handleChange"
      @on-created="handleCreated"
    />
  </div>
</template>

<style lang="less" scoped>
// 变量来自@wangeditor/editor/dist/css/style.css
.border-1-solid {
  border: 1px solid var(--w-e-toolbar-border-color);
}
.border-bottom-1-solid {
  border-bottom: 1px solid var(--w-e-toolbar-border-color);
}
</style>
